﻿using System;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace Innovator
{
	public class Actor : Component, I3DComponent
	{
		Model model;
		//I3DComponent values
		public virtual Vector3 Position { get; set; }
		public Vector3 EulerRotation
		{
			get { return MathUtil.MatrixToVector3(Rotation); }
			set { Rotation = MathUtil.Vector3ToMatrix(value); }
		}
		public virtual Matrix Rotation { get; set; }
		public virtual Vector3 Scale { get; set; }
		public virtual BoundingBox BoundingBox
		{
			get { return new BoundingBox(Position - (Scale / 2), Position + (Scale / 2)); }
		}
		//constructor
		public Actor(Model Model, Vector3 Position):base()
		{
			Setup(Model, Position);
		}
		public Actor(Model Model, Vector3 Position, GameScreen Parent):base(Parent)
		{
			Setup(Model, Position);
		}
		//setup actor
		void Setup(Model Model, Vector3 Position)
		{
			this.model = Model;
			this.Position = Position;
			Scale = Vector3.One;
			EulerRotation = Vector3.Zero;
		}
		public override void Draw()
		{
			Camera camera = Engine.Services.GetService<Camera>();
			if (camera == null)
				throw new Exception("Camera not found in engine's services, cannot draw");
			Matrix world = MathUtil.CreateWorldMatrix(Position, Rotation, Scale);
			Matrix[] transforms = new Matrix[model.Bones.Count];
			model.CopyAbsoluteBoneTransformsTo(transforms);
			//set renderstates
			Engine.GraphicsDevice.RenderState.AlphaBlendEnable = true;
			Engine.GraphicsDevice.RenderState.SourceBlend = Blend.SourceAlpha;
			Engine.GraphicsDevice.RenderState.DestinationBlend = Blend.InverseSourceAlpha;
			Engine.GraphicsDevice.RenderState.DepthBufferEnable = true;
			//loop through meshes and effects and set them up to draw
			foreach (ModelMesh mesh in model.Meshes)
			{
				foreach (BasicEffect effect in mesh.Effects)
				{
					effect.Parameters["World"].SetValue(transforms[mesh.ParentBone.Index] * world);
					effect.Parameters["View"].SetValue(camera.View);
					effect.Parameters["Projection"].SetValue(camera.Projection);
					effect.EnableDefaultLighting();
				}
				mesh.Draw();
			}
		}
	}
}